	package elements.axis ;
	import flash.display.Sprite;
	import string.Utils;
	import ColorConverter.Color;
	
	class YAxisBase extends Sprite {
		
		 var stroke: Float;
		 var tick_length: Float;
		 var color: Int;
		 var grid_color: Int;
		
		public var style:Dynamic;
		
		 var labels:YAxisLabelsBase;
		 var user_labels:Array<String>;
		 var user_ticks:Bool;
		
		public function new( json:Dynamic, name:String )
		{
			super();
			//
			// If we set this.style in the parent, then
			// access it here it is null, but if we do
			// this hack then it is OK:
			//
			this.style = this.get_style();
			
			if( Reflect.hasField(json,name) )
				ObjectHelper.merge_2( Reflect.field(json,name), this.style );

			var _style_color : Int = cast(style.color, Int);
			var _grid_color : Int = cast(style.grid_color, Int);
			
			this.color = ColorConverter.toInt(Hex(_style_color)); //Utils.get_color( style.color );
			this.grid_color = ColorConverter.toInt(Hex(_grid_color)); //Utils.get_color( style.grid_color );
			this.stroke = style.stroke;
			this.tick_length = style.tick_length;
			
			// try to aVoid infinate loops...
			if ( this.style.steps == 0 )
				this.style.steps = 1;
				
			if ( this.style.steps < 0 )
				this.style.steps *= -1;
			
			if (
				Reflect.hasField(this.style, "labels")
				&& Reflect.hasField(this.style.labels, "labels")
				&& Std.is(this.style.labels.labels,Array)
				&& this.style.labels.labels.length > 0
			)
			{
				this.user_labels = new Array<String>();
				var labels = cast(this.style.labels.labels, Array<String>);
				for ( lbl in labels )
				{
					if (!Std.is(lbl,String)) {
						if (lbl.y != null) 
						{
							var tmpObj:Dynamic = { y: lbl.y };
							if (Reflect.hasField(lbl,'grid_color'))
							{
								tmpObj.grid_color = Utils.get_color(lbl.grid_color);

							}
							else
							{
								tmpObj.grid_color = this.grid_color;
							}
							
							this.user_ticks = true;
							this.user_labels.push(tmpObj);
						}
					}
				}
			}

			
		}
		
		public function get_style():Dynamic { return null;  }
		
		//
		// may be called by the labels
		//
		public function set_y_max( m: Float ):Void {
			this.style.max = m;

		}
		
		public function get_range():Range {
			return new Range( this.style.min, this.style.max, this.style.steps, this.style.offset );
		}
		
		public function get_width(): Float {
			return this.stroke + this.tick_length + this.labels.width;
		}
		
		public function die(): Void {
			
			//this.offset = null;
			this.style = null;
			if (this.labels != null) this.labels.die();
			this.labels = null;
			
			this.graphics.clear();
			while ( this.numChildren > 0 )
				this.removeChildAt(0);
		}
		
		public function resize(label_pos: Float, sc:ScreenCoords):Void { }
		
		 function resize_helper(label_pos: Float, sc:ScreenCoords, right:Bool):Void {
			
			if( !right )
				this.labels.resize( label_pos, sc );
			else
				this.labels.resize( sc.right + this.stroke + this.tick_length, sc );
			
			if ( !this.style.visible )
				return;
			
			this.graphics.clear();
			this.graphics.lineStyle( 0, 0, 0 );
			
			// y axel grid lines
			//var every: Float = (this.minmax.y_max - this.minmax.y_min) / this.steps;
			
			// Set opacity for the first line to 0 (otherwise it overlaps the x-axel line)
			//
			// Bug? Does this work on graphs with minus values?
			//
			var i2: Float = 0;
			var i: Float;
			var y: Float;
			
			var min: Float = Math.min(this.style.min, this.style.max);
			var max: Float = Math.max(this.style.min, this.style.max);
			
			if ( Reflect.field(this.style,'grid-visible') ) {
				//
				// draw GRID lines
				//
				if (this.user_ticks) 
				{
					for ( lbl in this.user_labels )
					{
						y = sc.get_y_from_val(lbl.y, right);
						this.graphics.beginFill(Reflect.field(lbl,"grid-color"), 1);
						this.graphics.drawRect( sc.left, y, sc.width, 1 );
						this.graphics.endFill();
					}
				}
				else
				{
					//
					// hack: http://kb.adobe.com/selfservice/viewContent.do?externalId=tn_13989&sliceId=1
					//
					max += 0.000004;
					var i : Int = Std.int(min);
					while (i <= max)
					{
						y = sc.get_y_from_val(i, right);
						this.graphics.beginFill( this.grid_color, 1 );
						this.graphics.drawRect( sc.left, y, sc.width, 1 );
						this.graphics.endFill();

						i+=this.style.steps;
					}
/*					// outcommented
					for( i = min; i <= max; i+=this.style.steps ) {
						
						y = sc.get_y_from_val(i, right);
						this.graphics.beginFill( this.grid_color, 1 );
						this.graphics.drawRect( sc.left, y, sc.width, 1 );
						this.graphics.endFill();
					}
*/
				}
			}
			
			var pos: Float;
			
			if (!right)
				pos = sc.left - this.stroke;
			else
				pos = sc.right;
			
			// Axis line:
			this.graphics.beginFill( this.color, 1 );
			this.graphics.drawRect( pos, sc.top, this.stroke, sc.height );
			this.graphics.endFill();
			
			// ticks..
			var width: Float;
			var tick_pos: Float;
			if (this.user_ticks) 
			{
				for( lbl in this.user_labels )
				{
					y = sc.get_y_from_val(lbl.y, right);
					
					if ( !right )
						tick_pos = sc.left - this.stroke - this.tick_length;
					else
						tick_pos = sc.right + this.stroke;
					
					this.graphics.beginFill( this.color, 1 );
					this.graphics.drawRect( tick_pos, y - (this.stroke / 2), this.tick_length, this.stroke );
					//this.graphics.drawRect( pos - this.tick_length, y - (this.stroke / 2), this.tick_length, this.stroke );
					//this.graphics.drawRect( left, y-(this.stroke/2), this.tick_length, this.stroke );
					this.graphics.endFill();
				}
			}
			else
			{
				var i : Int = Std.int(min);
				while ( i<=max )
				{
					// start at the bottom and work up:
					y = sc.get_y_from_val(i, right);
					
					var tick_pos: Float;
					if ( !right )
						tick_pos = sc.left - this.stroke - this.tick_length;
					else
						tick_pos = sc.right + this.stroke;
					
					this.graphics.beginFill( this.color, 1 );
					this.graphics.drawRect( tick_pos, y - (this.stroke / 2), this.tick_length, this.stroke );
					//this.graphics.drawRect( pos - this.tick_length, y - (this.stroke / 2), this.tick_length, this.stroke );
					//this.graphics.drawRect( left, y-(this.stroke/2), this.tick_length, this.stroke );
					this.graphics.endFill();

					i+=this.style.steps;
				}
/*
				for( i = min; i <= max; i+=this.style.steps ) {
					
					// start at the bottom and work up:
					y = sc.get_y_from_val(i, right);
					
					var tick_pos: Float;
					if ( !right )
						tick_pos = sc.left - this.stroke - this.tick_length;
					else
						tick_pos = sc.right + this.stroke;
					
					this.graphics.beginFill( this.color, 1 );
					this.graphics.drawRect( tick_pos, y - (this.stroke / 2), this.tick_length, this.stroke );
					//this.graphics.drawRect( pos - this.tick_length, y - (this.stroke / 2), this.tick_length, this.stroke );
					//this.graphics.drawRect( left, y-(this.stroke/2), this.tick_length, this.stroke );
					this.graphics.endFill();
						
				}
*/
			}
		}
		
	}
